package br.ufrgs.engsoft.util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import br.ufrgs.engsoft.entity.Autor;
import br.ufrgs.engsoft.entity.Referencia;

/**
 * Classe utilitaria para manipulacao do codigo HTML. 
 */
public class HtmlUtil {
	
	/**
	 * Retorna o codigo HTML de um arquivo de interface com o usuario.
	 * @param fileName
	 * @return String
	 * @throws IOException 
	 */
	public static String getCodigoHtmlDaAcao(AcaoEnum page) throws IOException {
		String fileName = "/br/ufrgs/engsoft/ui/html/" + page.getFileName();
		StringBuffer retorno = new StringBuffer();

		URL resource = HtmlUtil.class.getResource(fileName);
		if (resource==null) throw new IOException("Arquivo "+fileName+" nao encontrado!");
		BufferedReader in = new BufferedReader(new FileReader(resource.getFile()));        
		String str;        
		while((str = in.readLine()) != null) {
			retorno.append(str);
		}
		in.close();
		
		return retorno.toString();
	}
	
	/**
	 * Substitui um conjunto de parametros em um codigo HTML.
	 * @param htmlCode
	 * @param parameters
	 * @return htmlCode
	 */
	public static String replaceParameters(String htmlCode, HashMap<HtmlParameterEnum, Object> parameters) {
		// Nao ha parametros a serem alterados
		if (parameters==null || parameters.size()==0) return htmlCode;

		Iterator<HtmlParameterEnum> keys = parameters.keySet().iterator();
		HtmlParameterEnum key = null;
		while (keys.hasNext()) {
			key = keys.next();
			htmlCode = replaceParameter(htmlCode, key, parameters.get(key));
		}
		return htmlCode;
	}
	
	/**
	 * Substitui um parametro em um codigo HTML.
	 * @param htmlCode
	 * @param parametro
	 * @param value
	 * @return htmlCode
	 */
	public static String replaceParameter(String htmlCode, HtmlParameterEnum parametro, Object value) {
		if (value instanceof Collection)
			return htmlCode.replace("["+parametro.name()+"]", getOptionsHtmlCode((Collection) value));
		else if (value instanceof Throwable)
			return htmlCode.replace("["+parametro.name()+"]", getHtmlCode((Throwable) value));
		else
			return htmlCode.replace("["+parametro.name()+"]", (String)value);
		
	}
	
	/**
	 * Varre uma excecao em busca da mensagem de erro.
	 * @param e
	 * @return String
	 */
	private static String getHtmlCode(Throwable e) {
		if (e.getMessage()==null && e.getCause()==null) return e.toString();
		if (e.getMessage()==null) return getHtmlCode(e.getCause());
		return e.getMessage();
	}

	/**
	 * Para gerar codigo HTML em campo do tipo select.
	 */
	private static String getOptionsHtmlCode(Collection options) {
		StringBuffer sb = new StringBuffer();
		for (Object option : options)
			if (option instanceof Autor) 
				sb.append(getOption((Autor) option));
			else if(option instanceof Referencia) 
					sb.append(getOption((Referencia) option));
		return sb.toString();
	}

	/**
	 * Para gerar codigo HTML a partir da entidade Autor.
	 * @param autor
	 * @return htmlCode
	 */
	private static String getOption(Autor autor) {
		return "<option value=\""+((Autor) autor).getId()+"\">"+((Autor) autor).getNomeSobrenome()+"</option>";
	}

	/**
	 * Para gerar codigo HTML a partir da entidade Autor.
	 * @param ref
	 * @return htmlCode
	 */
	private static String getOption(Referencia ref) {
		return "<tr>" + "<td class=\"linha\">"+((Referencia) ref).getAnoPublicacao()+"</td>"+
						"<td class=\"linha\">"+((Referencia) ref).getTitulo()+"</td>"+
						"<td class=\"linha\">"+((Referencia) ref).getAutor().getNomeSobrenome()+"</td>"+
						"<td class=\"linha\">"+((Referencia) ref).getId()+"</td>"+"</tr>";

	}
}
